<template>
  <el-select style="width: 100%" v-model="propsValue" :placeholder="placeholder" :multiple="multiple"
    :clearable="clearable" :multiple-limit="multipleLimit" :size="realSize" :disabled="realDisabled"
    :validate-event="false" :filter-method="bindFilterMethod" :filterable="filterable">
    <el-option v-for="item in state.options" :key="item[realProps.value]" :label="item[realProps.label]"
      :value="item[realProps.value]" :disabled="item[realProps.disabled] === '1'" />
  </el-select>
</template>

<script setup name="customSelectCode">
import { useFormItem, useFormItemInputId, useFormSize, useFormDisabled } from 'element-plus'
import { nextTick } from 'vue';
const props = defineProps({
  modelValue: {
    type: [Array, String, Number, Boolean, Object],
    default: ''
  },
  dataList: {
    type: Array,
    default: () => []
  },
  placeholder: {
    type: String,
    default: ''
  },
  props: {
    type: Object,
    default: () => ({})
  },
  code: {
    type: String,
    default: ''
  },
  separator: {
    type: String,
    default: '/'
  },
  validateEvent: {
    type: Boolean,
    default: true
  },
  size: {
    type: String,
    default: ''
  },
  filterable: Boolean,
  disabled: Boolean,
  clearable: Boolean,
  multiple: Boolean,
  multipleLimit: {
    type: Number,
    default: 0
  }
})
const { form, formItem } = useFormItem()
const { inputId } = useFormItemInputId(props, { formItemContext: formItem })
const formSize = useFormSize()
const formDisabled = useFormDisabled()
const { proxy } = getCurrentInstance();
const emit = defineEmits(['update:modelValue', 'change'])
const propsValue = computed({
  get: () => props.modelValue,
  set: (value) => {
    emit('update:modelValue', value)
    nextTick(() => {
      emit('change', value)
    })
  }
})
const realSize = computed(() => {
  return props.size || formSize.value
})
const realProps = computed(() => {
  return Object.assign({ label: 'label', value: 'value', disabled: 'status' }, props.props)
})
const realDisabled = computed(() => {
  return props.disabled || formDisabled.value
})
const state = reactive({
  options: []
})
let tempList = null
const bindFilterMethod = (query) => {
  if (!tempList) {
    tempList = state.options
  }
  state.options = query ? tempList.filter((item) => {
    return item[realProps.value.label].includes(query)
  }) : tempList
}
const valueWatch = watch(() => props.modelValue, (v) => {
  nextTick(() => {
    if (props.validateEvent) {
      formItem?.validate?.('change').catch((err) => console.log(err))
    }
  })
})
const codeWatch = watch(() => props.code, (v) => {
  v && getDataList()
})
const dataListWatch = watch(() => props.dataList, (v) => {
  v && (state.options = v)
})
const getDataList = () => {
  const dict = proxy.useDict(props.code)
  state.options = dict[props.code]
}
(props.code || props.group) && getDataList()
props.dataList.length && (state.options = props.dataList)
defineExpose({
  getValueLabel: () => {
    return Array.isArray(propsValue.value) ? proxy.selectDictLabels(state.options.value, propsValue, props.separator) : proxy.selectDictLabel(state.options.value, propsValue)
  },
  getSelectionOtherKey: (key) => {
    if (key && propsValue.value) {
      const item = state.options.find((item) => {
        return item[realProps.value.value] === propsValue.value
      })
      if (item) return item[key]
    }
    return ''
  },
})
</script>

<style lang="scss" scoped></style>